package com.angel.resourceBundle.managers;

import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.angel.common.helpers.StringHelper;
import com.angel.dao.generic.exceptions.OnDeleteHibernateException;
import com.angel.dao.generic.interfaces.GenericDAO;
import com.angel.resourceBundle.contexts.ResourceBundleContext;
import com.angel.resourceBundle.exceptions.InvalidPropertyValueKeyException;
import com.angel.resourceBundle.exceptions.OnRegisterPropertyValueException;
import com.angel.resourceBundle.exceptions.ResourceBundleException;
import com.angel.resourceBundle.propertyValue.PropertyValue;
import com.angel.resourceBundle.propertyValue.impl.SimplePropertyValue;
import com.angel.resourceBundle.results.PropertyValueResult;
import com.angel.resourceBundle.results.impl.PropertyValueResultImpl;


/**
 *
 * @author William
 *
 */
public class SimpleResourceBundleManager extends ResourceBundleManager{

	private static final Logger LOGGER = Logger.getLogger(SimpleResourceBundleManager.class);

	@SuppressWarnings("unchecked")
	public SimpleResourceBundleManager(ResourceBundleContext resourceBundleContext, GenericDAO propertyValueDAO){
		super(resourceBundleContext, propertyValueDAO);
	}

	/** Register a property value for a specific language.
	 *
	 * @param propertyValueKey to generate property.
	 * @param label to be internationalized.
	 * @param languageName associated to property key and its value (label).
	 * @throws OnRegisterPropertyValueException when an error occurs registering a property value.
	 * @throws InvalidPropertyValueKeyException when property value key is an empty or null value. This exception is not checked.
	 */
	public void registerPropertyValue(String propertyValueKey, String label, String languageName) throws OnRegisterPropertyValueException {
		String extendedKey = null;
		if(StringHelper.isNotEmpty(propertyValueKey)){
			LOGGER.info("Generating key for property value key [" + propertyValueKey + "].");
			extendedKey = this.getResourceBundleContext().generateExtendedKey(propertyValueKey, languageName);

			LOGGER.info("Extended key generated [" + extendedKey + "] for property value key [" + propertyValueKey + "].");

			LOGGER.info("Creating property value instance.");
			SimplePropertyValue propertyValue = this.createPropertyValueInstance();
			propertyValue.setExtendedKey(extendedKey);
			propertyValue.setLanguageName(languageName);
			propertyValue.setLabel(label);

			LOGGER.info("Updating property value.");
			super.getResourceBundleContext().updatePropertyValue(propertyValue);

			LOGGER.info("Registering property value.");
			super.registerPropertyValue(propertyValue);
		} else {
			throw new InvalidPropertyValueKeyException("Invalid property value key [" + propertyValueKey + "]. Property value key must NOT be a null or empty value.");
		}
	}

	public void registerPropertyValue(String propertyValueKey, String label) throws ResourceBundleException{
		String extendedKey = null;
		if(StringHelper.isNotEmpty(propertyValueKey)){
			LOGGER.info("Generating key for property value key [" + propertyValueKey + "].");
			extendedKey = this.getResourceBundleContext().generateExtendedKey(propertyValueKey);

			LOGGER.info("Extended key generated [" + extendedKey + "].");

			LOGGER.info("Creating property value instance.");
			SimplePropertyValue propertyValue = this.createPropertyValueInstance();

			propertyValue.setExtendedKey(extendedKey);

			propertyValue.setLanguageName(this.getResourceBundleContext().getCurrentLanguageName());

			propertyValue.setLabel(label);

			LOGGER.info("Updating property value.");
			super.getResourceBundleContext().updatePropertyValue(propertyValue);

			LOGGER.info("Registering property value.");
			super.registerPropertyValue(propertyValue);
		} else {
			throw new InvalidPropertyValueKeyException("Invalid property value key [" + propertyValueKey + "]. Property value key must NOT be a null or empty value.");
		}
	}

	@Override
	protected SimplePropertyValue createPropertyValueInstance() {
		return new SimplePropertyValue();
	}

	/** Find all properties values for a specific language name.
	 *
	 * @param languageName to find all its properties values.
	 * @return a property value result with all properties values found.
	 */
	public PropertyValueResult findAllPropertiesValuesWithLanguageName(String languageName) {
		String resourceBunbleKey = super.getResourceBundleContext().generateResourceBundleContextKey(languageName);
		List<PropertyValue> propertyValues = (List<PropertyValue>) super.getPropertyValueDAO().findAllByResourceBundleContextKey(resourceBunbleKey);
		return new PropertyValueResultImpl(propertyValues, resourceBunbleKey, super.getResourceBundleContext().getKeySeparator());
	}

	public PropertyValueResult findAllPropertiesValues() {
		String resourceBunbleKey = super.getResourceBundleContext().generateResourceBundleContextKey();
		List<PropertyValue> propertyValues = (List<PropertyValue>) super.getPropertyValueDAO().findAllByResourceBundleContextKey(resourceBunbleKey);
		return new PropertyValueResultImpl(propertyValues, resourceBunbleKey,super.getResourceBundleContext().getKeySeparator());
	}



	public void removePropertyValueWith(String propertyValueKey) throws ResourceBundleException {
		try {
			String extendedKey = super.getResourceBundleContext().generateExtendedKey(propertyValueKey);
			Long count = super.getPropertyValueDAO().countAllWithExtendedKey(extendedKey);
			if(count.longValue() == 0){
				throw new ResourceBundleException("Property value ["+ propertyValueKey + "] with extended key [" + extendedKey + "] not found.");
			}
			LOGGER.info("Removing [" + count + "] properties values instances with extended key [" + extendedKey + "] for resource bundle context [" + super.getResourceBundleContext().generateResourceBundleContextKey() + "].");
			super.getPropertyValueDAO().deleteUniqueByExtendedKey(extendedKey);
		} catch (OnDeleteHibernateException e){
			throw new ResourceBundleException("Error occurred removing property value [" + propertyValueKey + "].",e);
		}
	}

	public void registerPropertiesValues(Map<String, String> propertiesValues) throws ResourceBundleException {
		if(propertiesValues != null && propertiesValues.size() > 0){
			LOGGER.info("Registering [" + propertiesValues.size() + "] properties values.");
			for(String propertyValueKey: propertiesValues.keySet()){
				this.registerPropertyValue(propertyValueKey, propertiesValues.get(propertyValueKey));
			}
		}
	}

	/** Find an unique property value with a key and its current resource bundle language.
	 *
	 * @param propertyValueKey to find its value.
	 * @return property value for a property key.
	 */
	public String findUniquePropertyValueForKey(String propertyValueKey) {
		String extendedKey = super.getResourceBundleContext().generateExtendedKey(propertyValueKey);
		String contextKey = super.getResourceBundleContext().generateResourceBundleContextKey();

		LOGGER.info("Finding property value [" + propertyValueKey + "]  with extended key [" +
					extendedKey + "] for resource bundle context [" + contextKey + "].");

		PropertyValue propertyValue = super.getPropertyValueDAO().findUniqueByExtendedKey(extendedKey);
		return propertyValue != null ? propertyValue.getText(): StringHelper.EMPTY_STRING;
	}

	/** Find an unique property value for a key and a specific language name. If property value doesn't
	 * exist it return an empty value.
	 *
	 * @see StringHelper.EMPTY_STRING.
	 * @param languageName to find a property value.
	 * @param propertyValueKey to generate a property value to find.
	 * @return property value for a property key.
	 */
	public String findUniquePropertyValueFor(String languageName, String propertyValueKey) {
		String extendedKey = super.getResourceBundleContext().generateExtendedKey(propertyValueKey, languageName);
		String contextKey = super.getResourceBundleContext().generateResourceBundleContextKey(languageName);
		LOGGER.info("Finding property value [" + propertyValueKey + "]  with extended key [" + extendedKey
					+ "] for resource bundle context [" + contextKey + "].");
		SimplePropertyValue propertyValue = (SimplePropertyValue) super.getPropertyValueDAO().findUniqueByExtendedKey(extendedKey);
		return propertyValue != null ? propertyValue.getLabel(): StringHelper.EMPTY_STRING;
	}

	/** Find all properties values for a property value key.
	 *
	 * @param propertyValueKey to find all its properties values.
	 * @return a property value result with all its properties values.
	 */
	public PropertyValueResult findAllPropertiesValuesFor(String propertyValueKey) {
		String resourceBundleContextKey = super.getResourceBundleContext().generateResourceBundleContextKey();
		List<PropertyValue> propertyValues = (List<PropertyValue>) super.getPropertyValueDAO().findAllByResourceBundleContextKey(resourceBundleContextKey);
		return new PropertyValueResultImpl(propertyValues, resourceBundleContextKey, super.getResourceBundleContext().getKeySeparator());
	}
}
